package com.atguigu.gmall.all.controller.api;

import com.atguigu.gmall.common.result.Result;
import com.atguigu.gmall.model.product.BaseCategoryView;
import com.atguigu.gmall.product.client.feign.ProductFeignClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.thymeleaf.TemplateEngine;
import org.thymeleaf.context.Context;

import java.io.FileNotFoundException;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author wk
 * @create 2021-09-02 21:11
 * 首页
 */
@Controller
public class IndexController {

    @Autowired
    private ProductFeignClient productFeignClient;

    @Autowired
    private TemplateEngine templateEngine; // thymeleaf的模板引擎 用来生成HTML

    // 首页访问地址 https://gmall.com/
    @GetMapping("/")
    public String index(Model model) {
        // 封装要给页面展示的数据
        List<Map> category1IdListMap = getData();
        // 3.组装数据
        model.addAttribute("list", category1IdListMap);// 为页面返回数据
        return "index/index";
    }

    /**
     * 使用静态化技术 将生成的页面生成到指定文件下 在Linux系统中 挂载到nginx的某个目录下
     * nginx可以直接访问 进行临时缓存
     *
     * @return
     */
    @GetMapping("/createHtml")
    @ResponseBody
    public Result createHtml() {
        // 1.查询数据
        List<Map> data = getData();
        Context context = new Context();
        context.setVariable("list", data);
        // 2.准备模板 index页面已经存在
        // 3.生成文件
        Writer writer = null;
        try {
            // 生成模板到指定目录
            // 使用PrintWriter可以设置字符编码 避免出现乱码
            writer = new PrintWriter("E:\\temp\\index.html", "UTF-8");
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        // 参数1：模板名称
        // 参数2：数据
        // 参数3：输出流
        templateEngine.process("index/index", context, writer);
        return Result.ok();
    }

    /**
     * 获取首页数据
     *
     * @return
     */
    public List<Map> getData() {
        // 1.数据准备
        List<BaseCategoryView> baseCategoryViewList = productFeignClient.getBaseCategoryViewList();
        List<Map> category1IdListMap = new ArrayList<>();
        // 使用stream()流分组
        // 根据一级分类id进行分组
        // k:表示一级分类id
        // v:表示根据一级分类id进行分组后 一级id下所有的数据
        Map<Long, List<BaseCategoryView>> category1IdMapGroup =
                baseCategoryViewList.stream().collect(Collectors.groupingBy(BaseCategoryView::getCategory1Id));
        // 2.准备和页面数据所需要的数据结构
        // 遍历根据一级分类id进行分组 后的结果
        // 也可以使用JSONObject 它是对Map的封装
        int index = 1;
        for (Map.Entry<Long, List<BaseCategoryView>> category1IdMapEntry : category1IdMapGroup.entrySet()) {
            Map category1IdMap = new HashMap();
            category1IdMap.put("index", index);
            // 获取一级标题对应的标题名
            category1IdMap.put("categoryName", category1IdMapEntry.getValue().get(0).getCategory1Name());
            category1IdMap.put("categoryId", category1IdMapEntry.getKey());

            // 组装 categoryChild的数据 又是多个 需要列表接收
            List<Map> category2IdListMap = new ArrayList<>();
            // 再按照一级分类之后的结果数据value值基础上进行再次筛选
            List<BaseCategoryView> category2IdMapEntryValue = category1IdMapEntry.getValue();
            Map<Long, List<BaseCategoryView>> category2IdMapGroup = category2IdMapEntryValue.stream().
                    collect(Collectors.groupingBy(BaseCategoryView::getCategory2Id));
            // k:为二级分类id
            // v:在一级id分组后再根据二级id分组后数据
            for (Map.Entry<Long, List<BaseCategoryView>> category2IdMapEntry : category2IdMapGroup.entrySet()) {
                Map category2IdMap = new HashMap<>();
                category2IdMap.put("categoryName", category2IdMapEntry.getValue().get(0).getCategory2Name());
                category2IdMap.put("categoryId", category2IdMapEntry.getKey());

                List<Map> category3IdListMap = new ArrayList<>();
                // 无需再进行分组
                // 直接可以在二级查询后的结果上进行查询
                List<BaseCategoryView> category2IdMapEntryList = category2IdMapEntry.getValue();
                for (BaseCategoryView baseCategoryView : category2IdMapEntryList) {
                    Map category3IdMap = new HashMap<>();
                    category3IdMap.put("categoryName", baseCategoryView.getCategory3Name());
                    category3IdMap.put("categoryId", baseCategoryView.getCategory3Id());
                    category3IdListMap.add(category3IdMap);
                }
                // 添加二级分类的子节点
                category2IdMap.put("categoryChild", category3IdListMap);
                category2IdListMap.add(category2IdMap);
            }
            // 添加一级分类的子节点
            category1IdMap.put("categoryChild", category2IdListMap);
            category1IdListMap.add(category1IdMap);
        }
        return category1IdListMap;
    }
}
